package com.controladores.controlvehicular.comunicacion;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;

import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;

import android.content.Context;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;

import com.controladores.controlvehicular.Main;
import com.controladores.controlvehicular.basededatos.GestorBaseDatos;
import com.controladores.controlvehicular.estructura.RegistroExonerado;
import com.controladores.controlvehicular.estructura.RegistroMulta;
import com.controladores.controlvehicular.estructura.RegistroTarjeta;


public class ComunicacionTCP {
	private String ip = "";
	private int puerto = 0;
	Socket socket;
	DataInputStream entrada;
	DataOutputStream salida;
	
	private String informacionRegistro;
	private String[] datosRecibidos;
	private String claveEncriptacion="SI@P/ml*vc#";

	public DataInputStream getEntrada() {
		return entrada;
		
	}

	public void setEntrada(DataInputStream entrada) {
		this.entrada = entrada;
	}

	public DataOutputStream getSalida() {
		return salida;
	}

	public void setSalida(DataOutputStream salida) {
		this.salida = salida;
	}
	
	/**
	 * Obtiene la ip y el puerto para la comunicación
	 */
	public void abrirComunicacion() {
		GestorBaseDatos crear = new GestorBaseDatos(null);
		crear.abrirBaseDatos();
		ip = crear.obtenerIp();
		String x = "";
		x = crear.obtenerPuerto();
		puerto = Integer.parseInt(x);
		crear.close();
	}
	/**
	 * Verifica si se establece la comunicación
	 * @return Boolean Verdadero si se establece la comunicación, falso en caso contrario
	 */
	public boolean connect() {
		try {
			socket = new Socket(ip, puerto);
			if (socket.isConnected() == true) {
				return true;
			} else {
				return false;
			}
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}

	}
	/**
	 * Envia el mensaje al servidor 
	 * @param mensaje mensaje a enviar
	 */
	public void enviarMensaje(String mensaje) {
		try {
			salida = new DataOutputStream(new BufferedOutputStream(
					socket.getOutputStream()));
			salida.writeUTF(mensaje);
			salida.flush();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	/**
	 * Recibe el mensaje del servidor
	 * @return String mensaje
	 */
	public String recibirMensaje() {
		String mensajeRecibido = "";
		try {
			entrada = new DataInputStream(new BufferedInputStream(
					socket.getInputStream()));
			mensajeRecibido = getEntrada().readUTF();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return mensajeRecibido;
	}
	/**
	 * Desentrama cadena de datos 
	 * @param trama cadena de datos
	 * @return String[] lista de datos
	 */
	public String[] descomponerTrama(String trama) {
		String[] subtramas = trama.split(";");
		return subtramas;
	}
	/**
	 * Envía el código de la tarjeta para que sea validado 
	 * @param codigoT Código de la tarjeta
	 * @param usuario nombre de usuario
	 * @return String respuesta del servidor
	 */
	public String gestionarConexionValidarCodTarjeta(String codigoT, String usuario) {
		// TODO Auto-generated method stub
		abrirComunicacion();
		String salida = "";
		String informacion = "##;007;" + usuario +";"+ codigoT +";**";
		informacionRegistro=encriptar(informacion, claveEncriptacion);
		if (connect() == true) {
			enviarMensaje(informacionRegistro);
			String informacionRecibida=desencriptar(recibirMensaje(), claveEncriptacion);
			datosRecibidos = descomponerTrama(informacionRecibida);
			if (datosRecibidos[0].compareTo("##") == 0) {
				if (datosRecibidos[1].compareTo("008") == 0) {
					if (datosRecibidos[2].compareTo("1") == 0) {
						salida = "1";// codigo corecto
					}
					if (datosRecibidos[2].compareTo("0") == 0) {
						salida = "0";// crear nuevo codigo
					}
					if (datosRecibidos[2].compareTo("2") == 0) {
						salida = "2";// tarjeta caducada
					}
					if (datosRecibidos[2].compareTo("3") == 0) {
						salida = "3";// tarjeta fuera de rango 
					}
				}
			}
		} else {
			salida = "e";
		}
		return salida;
	}
	
	/**
	 * Envía los datos de un registro de tarjeta
	 * @param registroTarjeta objeto de tipo RegistroTarjeta
	 * @param mac dirección mac del dispositivo
	 * @return String respuesta del servidor
	 */
	public String gestionarConexionRegistroTarjeta(RegistroTarjeta registroTarjeta,String mac) {
		// TODO Auto-generated method stub
		String salida = "";
		abrirComunicacion();
		String informacion = "##;009;" + registroTarjeta.getNombreControlador() + ";" + registroTarjeta.getNombreZona()+ ";"
				+ registroTarjeta.getIdSubCalle() + ";" + registroTarjeta.getFecha() + ";" +registroTarjeta.getHora()+ ";"
				+ registroTarjeta.getColor() + ";" +registroTarjeta.getPlaca() + ";" + registroTarjeta.getMarca()+ ";" + registroTarjeta.getEspaciosTarjeta()
				+ ";" + registroTarjeta.getHoraLlegada()+ ";" + registroTarjeta.getCodigo()+ ";"+mac+";**";
		System.out.println("_____ojo_-_->"+informacion); 
		informacionRegistro=encriptar(informacion, claveEncriptacion);
		if (connect() == true) {
			enviarMensaje(informacionRegistro);
			String informacionRecibida=desencriptar(recibirMensaje(), claveEncriptacion);
			datosRecibidos = descomponerTrama(informacionRecibida);
			if (datosRecibidos[0].compareTo("##") == 0) {
				if (datosRecibidos[1].compareTo("010") == 0) {
					if (datosRecibidos[2].compareTo("1") == 0) {
						salida = "1";// e registro se ha echo sin ninguna
										// novedad
						System.out.println("respuesta 1"); 
					}
					if (datosRecibidos[2].compareTo("0") == 0) {
						salida = "0";// existen espepacios ya utilizados..
						// multa Tarjeta borrada uso indebido tarjeta
						System.out.println("respuesta 0");
					}
					if (datosRecibidos[2].compareTo("2") == 0) {
						salida = "2";// llamar al menu desea crearlo codigo
						// ComunicacionTCP comunicacion = new ComunicacionTCP();
						// RegistrarTarjeta enviar =new RegistrarTarjeta();
						// enviar.menuRevicionCodigoTarjeta();
						System.out.println("respuesta 2");
					}
					if (datosRecibidos[2].compareTo("3") == 0) {
						salida = "3";// tarjeta vencida uso indebido tarjeta
						System.out.println("respuesta 3");
					}
					if (datosRecibidos[2].compareTo("4") == 0) {
						salida = "4";// tarjeta vencida uso indebido tarjeta
						System.out.println("respuesta 4");
					}
				}
			}
		} else {
			salida = "e";
			System.out.println("respuesta error");
		}

		return salida;
	}

	/**
	 * Envía datos de un Registro de Exonerado (Discapacidad) 
	 * @param registroExonerado objeto de tipo RegistroExonerado
	 * @param mac dirección mac del dispositivo
	 * @return String respuesta del servidor
	 */
	public String gestionarConexionRegistroExoneradoDiscapacitado(RegistroExonerado registroExonerado,String mac) {
		// TODO Auto-generated method stub
		String salida = "";
		abrirComunicacion();
		String informacion = "##;011;" +registroExonerado.getNombreControlador()+ ";" + registroExonerado.getNombreZona()
				+ ";" + registroExonerado.getIdSubCalle() + ";" + registroExonerado.getFecha() + ";" + registroExonerado.getHora()
				+ ";" + registroExonerado.getPlaca() +";"+mac+";**";
		informacionRegistro=encriptar(informacion, claveEncriptacion);
		if (connect() == true) {
			enviarMensaje(informacionRegistro);
			String informacionRecibida=desencriptar(recibirMensaje(), claveEncriptacion);
			datosRecibidos = descomponerTrama(informacionRecibida);
			if (datosRecibidos[0].compareTo("##") == 0) {
				if (datosRecibidos[1].compareTo("012") == 0) {
					if (datosRecibidos[2].compareTo("1") == 0) {
						salida = "1";// Correcto
					}
					if (datosRecibidos[2].compareTo("0") == 0) {
						salida = "0";// etiquetaPlaca no existe
					}
				}
			}
		} else {
			salida = "e";
		}
		return salida;
	}
	
	/**
	 * Envía datos de un Registro Exonerado (Municipio)
	 * @param registroExonerado objeto de tipo RegistroExonerado
	 * @param mac dirección mac del dispositivo
	 * @return String respuesta del servidor
	 */
	public String gestionarConexionRegistroExoneradoMunicipio(RegistroExonerado registroExonerado,String mac) {
		// TODO Auto-generated method stub
		String salida = "";
		abrirComunicacion();
		
		String informacion = "##;011;" + registroExonerado.getNombreControlador()+ ";" + registroExonerado.getNombreZona()
				+ ";" + registroExonerado.getIdSubCalle() + ";" + registroExonerado.getFecha()+ ";" + registroExonerado.getHora()
				+ ";" + registroExonerado.getPlaca()+";"+mac+";**";
		informacionRegistro=encriptar(informacion, claveEncriptacion);
		if (connect() == true) {
			enviarMensaje(informacionRegistro);
			String informacionRecibida=desencriptar(recibirMensaje(), claveEncriptacion);
			datosRecibidos = descomponerTrama(informacionRecibida);
			if (datosRecibidos[0].compareTo("##") == 0) {
				if (datosRecibidos[1].compareTo("012") == 0) {
					if (datosRecibidos[2].compareTo("1") == 0) {
						salida = "1";// Correcto
					}
				}
			}
		} else {
			salida = "e";
		}
		return salida;
	}

	/**
	 * Envía datos de un registro de multa calculada por el sistema
	 * @param registroMulta objeto de tipo RegistroMulta
	 * @param mac dirección mac del dispositivo
	 * @return String respuesta del servidor
	 */
	public String gestionarConexionRegistroMultaSistTarjeta(RegistroMulta registroMulta,String mac) {
		// TODO Auto-generated method stub
		String salida = "";
		abrirComunicacion();
		String informacion = "##;013;" + registroMulta.getNombreControlador() + ";" + registroMulta.getNombreZona()
				+ ";" + registroMulta.getIdSubCalle() + ";" + registroMulta.getFecha() + ";" + registroMulta.getHora() + ";" + registroMulta.getPlaca()
				+ ";" + registroMulta.getCodigo()+ ";" + registroMulta.getNombreInfractor() + ";" + registroMulta.getIdMultaServidor() +";"+mac+ ";**";
		informacionRegistro=encriptar(informacion, claveEncriptacion);
		if (connect() == true) {
			enviarMensaje(informacionRegistro);
			String informacionRecibida=desencriptar(recibirMensaje(), claveEncriptacion);
			datosRecibidos = descomponerTrama(informacionRecibida);
			if (datosRecibidos[0].compareTo("##") == 0) {
				if (datosRecibidos[1].compareTo("014") == 0) {
					if (datosRecibidos[2].compareTo("1") == 0) {
						salida = "1";// Correcto
					}
					if (datosRecibidos[2].compareTo("0") == 0) {
						salida = "0";// Revisar codigo Usado
					}
				}
			}
		} else {
			salida = "e";
		}
		return salida;
	}
	
	/**
	 * Envía datos de un registro de multa
	 * @param registroMulta objeto de tipo RegistroMulta
	 * @param mac dirección mac del dispositivo
	 * @return String respuesta del servidor
	 */
	public String gestionarConexionEnviarMulta(RegistroMulta registroMulta,String mac) {
		// TODO Auto-generated method stub
		RegistroMulta registroDeMulta = registroMulta;
		String salida = "";
		abrirComunicacion();
		String informacion = "##;013;" + registroDeMulta.getNombreControlador() + ";" + registroDeMulta.getNombreZona()
				+ ";" + registroDeMulta.getIdSubCalle() + ";" + registroDeMulta.getFecha() + ";" + registroDeMulta.getHora() + ";" + registroDeMulta.getPlaca()
				+ ";" + registroDeMulta.getCodigo() + ";" + registroDeMulta.getNombreInfractor() + ";" + registroDeMulta.getIdMultaServidor() + ";"+mac+";**";
		informacionRegistro=encriptar(informacion, claveEncriptacion);
		if (connect() == true) {
			enviarMensaje(informacionRegistro);
			String informacionRecibida=desencriptar(recibirMensaje(), claveEncriptacion);
			datosRecibidos = descomponerTrama(informacionRecibida);
			if (datosRecibidos[0].compareTo("##") == 0) {
				if (datosRecibidos[1].compareTo("014") == 0) {
					if (datosRecibidos[2].compareTo("1") == 0) {
						salida = "1";// Correcto
					}
					if (datosRecibidos[2].compareTo("0") == 0) {
						salida = "0";// Revisar codigo Usado
					}
				}
			}
		} else {
			salida = "e";
		}
		return salida;
	}

	/**
	 * Envía la confirmación para almacenar el código de una tarjeta
	 * @param confirmacion mensaje de confirmación
	 * @param codigoT código de la tarjeta
	 * @param trama datos de registro
	 * @param usuario nombre de usuario
	 * @param mac dirección mac del dispositivo
	 * @return String respuesta del servidor
	 */
	public String gestionarConexionSmsConfirmacionValidacion(
			String confirmacion, String codigoT, String trama, String usuario,String mac) {
		// TODO Auto-generated method stub
		String salida = "";
		abrirComunicacion();
		String informacion = "##;" + trama+";"+ usuario + ";" + confirmacion + ";"
				+ codigoT + ";"+mac+";**";
		informacionRegistro=encriptar(informacion, claveEncriptacion);
		if (connect() == true) {
			enviarMensaje(informacionRegistro);
			String informacionRecibida=desencriptar(recibirMensaje(), claveEncriptacion);
			datosRecibidos = descomponerTrama(informacionRecibida);
			if (datosRecibidos[0].compareTo("##") == 0) {
				if (datosRecibidos[1].compareTo("016") == 0) {
					if (datosRecibidos[2].compareTo("1") == 0) {
						salida = "1";// Correcto se a enviado
					}
				}
			}
		} else {
			salida = "e";
		}
		return salida;
	}

	public String gestionarConexionSmsConfirmacionValidacionTarjetaN(
			String confirmacion, String usuario2, String nombreZona2,
			String idSubCalle2, String fechacontrol2, String horaControl2,
			String color2, String placa2, String marca2,
			String espaciosTarjeta2, String horallegada13, String codigoT2,String mac) {
		// TODO Auto-generated method stub
		String salida = "";
		abrirComunicacion();
		String informacion = "##;017;" + confirmacion + ";" + usuario2 + ";"
				+ nombreZona2 + ";" + idSubCalle2 + ";" + fechacontrol2 + ";"
				+ horaControl2 + ";"  + color2 + ";"
				+ placa2 + ";" + marca2 + ";"  + espaciosTarjeta2
				+ ";" + horallegada13 + ";" + codigoT2 +";"+mac+";**";
		informacionRegistro=encriptar(informacion, claveEncriptacion);
		if (connect() == true) {
			
			enviarMensaje(informacionRegistro);
		} else {
			salida = "e";
		}
		return salida;
	}
	
	/**
	 * Envía los datos de ubicación del usuario
	 * @param usuario nombre de usuario
	 * @param fecha fecha actual
	 * @param hora hora actual
	 * @param latitud latitud de ubicación
	 * @param longitud longitud de ubicación
	 * @param alarma estado de ubicación
	 * @return String respuesta del servidor
	 */
	public String gestionarConexionEnvioPosicion(String usuario,String fecha, String hora,String latitud, String longitud, String alarma){
		String salida="";
		abrirComunicacion();
		
		String informacion = "##;020;" + usuario + ";" + fecha + ";"
				+ hora + ";"  + latitud+";"+longitud+";"+alarma+";**";
		System.out.println("envio trama posiciones"+informacionRegistro);
		informacionRegistro=encriptar(informacion, claveEncriptacion);
		if (connect() == true) {
			enviarMensaje(informacionRegistro);
			String informacionRecibida=desencriptar(recibirMensaje(), claveEncriptacion);
			datosRecibidos = descomponerTrama(informacionRecibida);
			if (datosRecibidos[0].compareTo("##") == 0) {
				if (datosRecibidos[1].compareTo("021") == 0) {
					if (datosRecibidos[2].compareTo("1") == 0) {
						salida = "1";// Correcto
					}
				}
			}
		} else {
			salida = "e";
		}
		
		return salida;
	}

	/**
	 * Envía la confirmación de estacionamiento de un vehículo de recarga
	 * @param confirmacion mensaje de confirmación
	 * @param nombreUsuario nombre de usuario
	 * @param nombreZona nombre de Zona
	 * @param idSubcalle id de Subcalle
	 * @param fecha fecha actual
	 * @param horaActual hora actual
	 * @param placa placa del vehículo
	 * @param mac dirección mac del dispositivo
	 * @return String respuesta del servidor
	 */
	public String gestionarConexionConfirmacionVehiculoRecarga(String confirmacion,
			String nombreUsuario, String nombreZona, String idSubcalle, String fecha,
			String horaActual, String placa, String mac) {
		// TODO Auto-generated method stub
		String salida = "";
		abrirComunicacion();
		String informacion = "##;018;" + confirmacion + ";" + nombreUsuario + ";"
				+ nombreZona + ";" + idSubcalle + ";" + fecha + ";"
				+ horaActual + ";"  + placa + ";"+mac+
				 ";**";
		informacionRegistro=encriptar(informacion, claveEncriptacion);
		if (connect() == true) {
			enviarMensaje(informacionRegistro);
			String informacionRecibida=desencriptar(recibirMensaje(), claveEncriptacion);
			datosRecibidos = descomponerTrama(informacionRecibida);
			if (datosRecibidos[0].compareTo("##") == 0) {
				if (datosRecibidos[1].compareTo("019") == 0) {
					if (datosRecibidos[2].compareTo("1") == 0) {
						salida = "1";// Correcto
					}
				}
			}
		} else {
			salida = "e";
		}
		return salida;
	}

	/**
	 * Envía la información de un vehículo
	 * @param nombreUsuario nombre de usuario
	 * @param nombreZona nombre de zona
	 * @param idSubCalle id de subcalle
	 * @param espacioRegistro número de espacio de registro
	 * @param placa placa del vehículo
	 * @param color color del vehículo
	 * @param marca marca del vehículo
	 * @param horaControl hora actual
	 * @param fechacontrol fecha actual
	 * @param mac dirección mac del dispositivo
	 * @return String respuesta del servidor
	 */
	public String envioInformacionVehiculo(String nombreUsuario,
			String nombreZona, String idSubCalle,
			int espacioRegistro, String placa, String color, String marca,
			String horaControl, String fechacontrol,String mac) {
		// TODO Auto-generated method stub
		String salida = "";
		abrirComunicacion();
		String informacionRegistroS = "##;003;" + nombreUsuario + ";" + nombreZona
				+ ";" + idSubCalle + ";" + fechacontrol + ";" + horaControl
				+ ";" +color+";" + placa+";" + marca +";"+mac+";**";
		informacionRegistro=encriptar(informacionRegistroS, claveEncriptacion);
		System.out.println("envio trama informacion"+informacionRegistro);
		if (connect() == true) {
			enviarMensaje(informacionRegistro);
			String informacionRecibida=desencriptar(recibirMensaje(), claveEncriptacion);
			//datosRecibidos = descomposeTrama(receiveMensaje());
			datosRecibidos = descomponerTrama(informacionRecibida);
			if (datosRecibidos[0].compareTo("##") == 0) {
				if (datosRecibidos[1].compareTo("004") == 0) {
					if (datosRecibidos[2].compareTo("0") == 0) {
						salida = "0"; // el usuario no existe ni en la tabla exonerados ni en usuarios de recarga
					}
					if (datosRecibidos[2].compareTo("1") == 0) {
						salida = "1"; // el usuario es usuario de recarga
					}
					if (datosRecibidos[2].compareTo("2") == 0) {
						
						salida = "2"; // recarga el usuario es usuario de recarga y no ha activado el servicio
					}
					if (datosRecibidos[2].compareTo("3") == 0) {
						salida = "3"; // el usuario es exonerado
					}
				}
			}
		} else {
			salida = "e";
		}
		return salida;
	}

	public String envioInformacionVehiculoNoActivacionRecarga(
			String infousuario, String infoNombreZona, String infoIdSubCalle,
			int infoespacioRegistro, String placa, String color, String marca,
			String horaControl, String fechacontrol,String mac) {
		// TODO Auto-generated method stub
		String salida = "";
		abrirComunicacion();
		String informacion = "##;005;" + infousuario + ";" + infoNombreZona
				+ ";" + infoIdSubCalle + ";" + fechacontrol + ";" + horaControl
				+ ";" +color+";" + placa+";" + marca +";"+mac+";**";
		informacionRegistro=encriptar(informacion, claveEncriptacion);
		if (connect() == true) {
			enviarMensaje(informacionRegistro);
			String informacionRecibida=desencriptar(recibirMensaje(), claveEncriptacion);
			datosRecibidos = descomponerTrama(informacionRecibida);
			if (datosRecibidos[0].compareTo("##") == 0) {
				if (datosRecibidos[1].compareTo("006") == 0) {
					if (datosRecibidos[2].compareTo("1") == 0) {
						salida = "1"; // Datos enviados Corectamente
					}
				}
			}
		} else {
			salida = "e";
		}
		return salida;
	}
	
	/**
	 * Envía datos para eliminar la sesión
	 * @param nombreUsuario nombre de usuario
	 * @param confirmacion mensaje de confirmación
	 * @param mac dirección del dispositivo
	 * @return String respuesta del servidor
	 */
	public String gestionarConexionCerrarSesion(String nombreUsuario, String confirmacion,String mac) {
		// TODO Auto-generated method stub
		String salida = "";
		abrirComunicacion();
		String informacion = "##;022;" + nombreUsuario + ";" + confirmacion + ";"+mac+";**";
		informacionRegistro=encriptar(informacion, claveEncriptacion);
		if (connect() == true) {
			enviarMensaje(informacionRegistro);
			String informacionRecibida=desencriptar(recibirMensaje(), claveEncriptacion);
			datosRecibidos = descomponerTrama(informacionRecibida);
			if (datosRecibidos[0].compareTo("##") == 0) {
				if (datosRecibidos[1].compareTo("023") == 0) {
					if (datosRecibidos[2].compareTo("1") == 0) {
						salida = "1";// Correcto
					}
				}
			}
		} else {
			salida = "e";
		}
		return salida;
	}

	/**
	 * Envía los datos de las multas que aún no han sido almacenadas en el servidor
	 * @param datosSicronizar datos de multas
	 * @param mac dirección mac del dispositivo
	 * @return String respuesta del servidor
	 */
	public String gestionarConexionSicronizarMultas(String datosSicronizar,String mac) {
		// TODO Auto-generated method stub
		String salida = "";
		abrirComunicacion();
		String informacion = "##;024;" + datosSicronizar + ";"+mac+";**";
		informacionRegistro=encriptar(informacion, claveEncriptacion);
		if (connect() == true) {
			enviarMensaje(informacionRegistro);
			String informacionRecibida=desencriptar(recibirMensaje(), claveEncriptacion);
			datosRecibidos = descomponerTrama(informacionRecibida );
			if (datosRecibidos[0].compareTo("##") == 0) {
				if (datosRecibidos[1].compareTo("025") == 0) {
					if (datosRecibidos[2].compareTo("1") == 0) {
						salida = "1";// Correcto
					}
				}
			}
		} else {
			salida = "e";
		}
		return salida;
	}
	
	
	public static String encriptar(String cadena,String clave) { 
        StandardPBEStringEncryptor s = new StandardPBEStringEncryptor(); 
        s.setPassword(clave); 
        return s.encrypt(cadena); 
    }

	public static String desencriptar(String cadena,String clave) { 
	        StandardPBEStringEncryptor s = new StandardPBEStringEncryptor(); 
	        s.setPassword(clave); 
	        String devuelve = ""; 
	        try { 
	            devuelve = s.decrypt(cadena); 
	        } catch (Exception e) { 
	        } 
	        return devuelve;
	}
}
